Skip to content

CAMEL-24498: align camel-observability-services-starter defaults with the Spring Boot baseline - #1927

Merged
Croway merged 1 commit into
apache:mainfrom
Croway:CAMEL-24498-observability-defaults
Sep 3, 2026
Merged

CAMEL-24498: align camel-observability-services-starter defaults with the Spring Boot baseline#1927
Croway merged 1 commit into
apache:mainfrom
Croway:CAMEL-24498-observability-defaults

Conversation

@Croway

@Croway Croway commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes CAMEL-24498.

What

ObservabilityServicesEnvironmentPostProcessor injects a set of management defaults as soon as camel-observability-services-starter is on the classpath. Three of them were wider than the Spring Boot or Camel setting they replaced, and this PR brings them back in line.

Property Before After
management.server.address not set (listener on all interfaces) 127.0.0.1
management.endpoint.health.show-details always when-authorized
camel.health.exposure-level full not injected (Camel default default)

Everything else the starter injects is unchanged.

Why

  • management.server.port was injected with no matching management.server.address. Spring Boot ships no separate management listener at all, so the starter both opens the listener and, implicitly, put it on every interface. Opening it is the starter's job; deciding how far it reaches should be the operator's. camel-jolokia-starter binds its agent to loopback for the same reason.
  • show-details=always is two steps past the Spring Boot default of never. Camel health checks report on the resources a route talks to — broker connections, data sources, remote endpoints — and their detail can identify those resources. when-authorized shows the indicators to an authenticated caller and the overall status alone to everybody else; with no Spring Security on the classpath it behaves as never.
  • camel.health.exposure-level=full overrode the Camel default of default. At default, CamelHealthHelper filters health check metadata (endpoint URIs, route and consumer identifiers) out of the response and keeps check names, error messages and stack traces — so failure diagnosis is unaffected. full is now documented as an opt-in.

Why the live/ready groups keep show-details=always

The JIRA left this conditional on whether the Kubernetes probe flow needs it. It does, and it costs nothing:

  • The kubelet reads /observe/health/live and /observe/health/ready unauthenticated, so when-authorized would collapse to never for them.
  • The kubelet puts the (truncated) HTTP response body into the probe-failure event, so kubectl describe pod names the indicator that took the pod down. With never the operator only sees the status code.
  • Both groups contain availability-state indicators only. CamelLivenessStateHealthIndicator / CamelReadinessStateHealthIndicator extend Spring's LivenessStateHealthIndicator / ReadinessStateHealthIndicator, which report a status and contribute no details. So always on those groups reveals the indicator names and their UP/DOWN state, and nothing else.

Behaviour change and how to opt back in

The property source is still added with addLast, so every one of these is overridden by ordinary application configuration.

Kubernetes deployments whose kubelet probes or Prometheus scrapers reach the pod over the network must now widen the bind address explicitly:

management.server.address = 0.0.0.0

The other two:

management.endpoint.health.show-details = always
camel.health.exposure-level = full

This is called out in the starter docs and needs a note in the 4.23 upgrade guide in apache/camel (drafted separately, not part of this PR).

Docs

The starter had no hand-written doc sections. This PR adds src/main/doc/intro.adoc and src/main/doc/usage.adoc, which the generator folds into docs/spring-boot/modules/ROOT/pages/starters/observability-services.adoc (regenerated and committed). They document the endpoint layout, the full injected property set as a table, and a section each on the bind address, health detail exposure and the Camel exposure level.

A test asserts that the injected key set matches the documented table, so the two cannot drift apart silently.

Tests

mvn install -pl components-starter/camel-observability-services-starter — 10 tests, 0 failures.

  • ObservabilityServicesEnvironmentPostProcessorTest (7) — extended with managementListenerBindsToLoopback, aggregateHealthDetailsRequireAuthorization, probeGroupsKeepTheirDetails, camelHealthExposureLevelIsNotForced and injectedPropertiesAreTheDocumentedSet; the existing assertions for the removed/changed values were updated.
  • ObservabilityServicesOptInOverridesTest (3, new) — verifies each of the three settings can be opted back into from application configuration.

No Thread.sleep introduced; the tests are assertions over the Environment, so no waiting is involved.

Claude Code (Opus 5) on behalf of Federico Mariani

@Croway
Croway requested review from davsclaus and oscerd September 2, 2026 12:47
… the Spring Boot baseline

ObservabilityServicesEnvironmentPostProcessor injects a set of management
defaults as soon as the starter is on the classpath. Three of them were wider
than the Spring Boot or Camel setting they replaced:

- management.server.port was injected with no matching
  management.server.address, so adding the starter opened a second listener on
  every interface. Spring Boot ships no separate management listener at all.
  The listener now binds to 127.0.0.1, the same choice camel-jolokia-starter
  makes for its agent.
- management.endpoint.health.show-details was 'always' where the Spring Boot
  default is 'never'. The aggregate /observe/health endpoint now uses
  'when-authorized'. Camel health checks report on the resources a route talks
  to and their detail can identify those resources.
- camel.health.exposure-level was forced to 'full' where the Camel default is
  'default'. It is no longer injected; 'full' is documented as an opt-in.

The live and ready health groups keep show-details=always. The kubelet reads
them unauthenticated and puts the response body into the probe-failure event,
so 'kubectl describe pod' still names the indicator that took the pod down, and
both groups contain availability-state indicators only - livenessState,
readinessState and their Camel counterparts report a status and carry no data.

The property source is still added with addLast, so all of these remain
overridable by ordinary application configuration. Kubernetes deployments whose
probes or scrapers reach the pod over the network now have to set
management.server.address=0.0.0.0 explicitly.

Adds starter docs (src/main/doc/intro.adoc and usage.adoc) documenting the full
injected property set and how to opt back into each of the previous values, and
regenerates the starter doc page.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Croway
Croway force-pushed the CAMEL-24498-observability-defaults branch from b43fab0 to 2140eae Compare September 2, 2026 13:11
@Croway
Croway merged commit d22aa00 into apache:main Sep 3, 2026
5 checks passed
@oscerd

oscerd commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Is management.server.address now defaulted to loopback for the other components as well, or only here?

As far as I can see this starter is the only thing in the repo that opens a separate management listener, so there would be nothing to default elsewhere: management.server.port and management.server.address are set only in ObservabilityServicesEnvironmentPostProcessor, the other two EnvironmentPostProcessor implementations (CamelCloudConfigEnvironmentPostProcessor, CamelVirtualThreadEnvironmentPostProcessor) touch no management properties, and nothing references management.port or ManagementServerProperties. The other management.server.* hits are management.server.accesslog.*, which is our own access-log config rather than the bind address.

Spring Boot's own default is no separate management port at all, with actuator served on the main application port that the app already binds deliberately, and management.server.address only takes effect once a separate port is configured. So unless I have missed a starter that opens one, this is the only place that needed it.

Worth confirming though, since if another starter does grow a management listener later it will inherit the all-interfaces default again.

Comment by Claude Code on behalf of Andrea Cosentino.

@oscerd

oscerd commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

@Croway @squakez

@squakez

squakez commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

My concern is about a couple of additional points.

Do we need to extend this behavior to other components that are exposing an endpoint? The camel-observability-services is just a layer on top of existing components, camel-metrics, camel-health, ... etc.

Do we need to extend this to other runtimes to "harmonize" the security measures in place? The goal of camel-observability-services is to provide a sensible default configuration and avoid any external consumer to use it without knowing if the runtime it's coming is Spring Boot, Quarkus or Camel Main. It is worthy to clarify this aspect as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants